home *** CD-ROM | disk | FTP | other *** search
- PAGE ,80
- ;
- TITLE * START.ASM *
- SUBTTL Program to start processes at a predetermined time.
- ;
- ; CREATED 06-DEC-85 :RICHARD B JOHNSON
- ;
- IF1
- %OUT [PASS1]
- ELSE
- %OUT [PASS2]
- ENDIF
- ;
- ; Misc equates.
- ;
- CR EQU 0DH
- LF EQU 0AH
- MS_DOS EQU 21H ;SYSTEM
- CLK EQU 1CH ;TIMER VECTOR
- CLX EQU 08H ;BEGINNING OF TIMER VECTOR
- INT_BASE EQU 20H ;INTERRUPT CONTROLLER
- VID_ROM EQU 10H ;VIDEO ROM
- K EQU 1024
- K16 EQU 16 * K
- CMD_BUF EQU 80H ;COMMAND LINE
- RAM EQU 12H ;GET AVAILABLE RAM
- MAX_HRS EQU 23
- MAX_MIN EQU 59
- MAX_SEC EQU MAX_MIN
- EQUIP EQU 410H ;EQUIPMENT FLAG
- BWSEG EQU 0B000H ;SEGMENT FOR BLACK/WHITR
- COSEG EQU 0B800H ;SEGMENT FOR COLOR
- ;
- ;
- PSEG SEGMENT
- ASSUME CS:PSEG,SS:PSEG,DS:PSEG,ES:NOTHING
- ORG 100H
- MAIN PROC NEAR
- JMP INIT
- DB 'Copyright (C) 1985 Richard B. Johnson. '
- DB 'All rights reserved. '
- PRP0 DB CR,LF,'Process $'
- PRP1 DB CR,LF,'will start at '
- HH DB '00:'
- MM DB '00:'
- SX DB '00. If not correct, hit any key.... $'
- PRP2 DB ' aborted.',CR,LF,'$'
- PRP3 DB ' loaded.',CR,LF,'$'
- PRP4 DB CR,LF,'Usage:'
- DB CR,LF,'START HH:MM:SS \PATH\RUNFILE COMMAND STRING'
- DB CR,LF,LF,'Examples:'
- DB CR,LF,'START 23:55:00 C:\DOS\BACKUP.BAT TODAYS FILES'
- DB CR,LF,'START 12:00:00 \SETCLOCK'
- DB CR,LF,'START 15:00:00 COPY *.DAT E:'
- DB CR,LF,'$'
- PRP5: DB CR,LF,'The time entered must be LATER than the present '
- DB 'time!',CR,LF,'$'
- ;
- BEEP DB 7,'Your process will resume in a moment.'
- DB CR,LF,'$'
- ;
- ERRW DB CR,LF,'Not enough disk space to save the screen'
- DB CR,LF,'(need 16k).$'
- ;
- FILE1 DB '\SCREEN.TMP',0
- FILEN EQU $ - FILE1
- FILE2 DB ' ',0
- HANDLE DW ?
- ;
- CNT DB 182 ;LOCAL CLOCK TICK COUNT
- SEC DB ? ;LOCAL CLOCK SECONDS
- MIN DB ? ;LOCAL CLOCK MINUTES
- HRS DB ? ;LOCAL CLOCK HOURS
- SAV_SEC DB ? ;COMMAND STRING SECS (BINARY)
- SAV_MIN DB ? ;COMMAND STRING MINS (BINARY)
- SAV_HRS DB ? ;COMMAND STRING HRS (BINARY)
- SS_SAV DW ? ;USER'S STACK SEGMENT
- SP_SAV DW ? ;USER'S STACK POINTER
- COMMAND DB '\COMMAND.COM',0
- ;
- BLOCK DW 0 ;PARAMETER BLOCK FOR EXEC
- DW CMD_BUF ;DEFALUT BUFFER
- BP_1 DW ? ;CS WRITTEN HERE
- DW 5CH ;DEFAULT FCB
- BP_2 DW ? ;CS WRITTEN HERE
- DW 6CH ;OTHER FCB
- BP_3 DW ? ;CS WRITTEN HERE
- ;
- DTA_SEG DW ? ;USER'S DTA (SEGMENT)
- DTA_OFF DW ? ;USER'S DTA (OFFSET)
- SSP_SAV DW ? ;OUR STACK POINTER
- SAV_SEG DW ? ;OLD INTERRUPT SEGMENT
- SAV_OFF DW ? ;OLD INTERRUPT OFFSET
- CUR_SAV DW ? ;CURSOR SAVE
- CUR_TYP DW ? ;CURSOR TYPE
- CUR_PGE DB ? ;CURRENT PAGE
- OLD_CLK LABEL DWORD ;OLD TIMER VECTOR
- IP_CLK DW ? ;IP FOR OLD CLOCK
- CS_CLK DW ? ;CS FOR OLD CLOCK
- OLD_CLX LABEL DWORD ;START OF CLOCK VECT
- IP_CLX DW ? ;IP FOR START
- CS_CLX DW ? ;CS FOR START
- CRT_FLG LABEL DWORD ;CRITICAL FLAG (DOS)
- DOS_FLG DW ? ;CRITICAL FLAG ADDRESS
- DW ?
- SEGMNT DW ? ;VIDEO SEGMENT
- HERE DB 0 ;REENTRY FLAG
- DISK DB ? ;CURRENT DISK
- DIRZ DB '\'
- DIRECT DB 64 DUP (?) ;CURRENT DIRECTORY
- ;
- INFORM DB ' /C '
- BUFFER DB ' ' ;THE SPACE
- ASC_HRS DB 'HH:' ;HOURS IN ASCII
- ASC_MIN DB 'MM:' ;MINUTES IN ASCII
- NEW_CMD EQU $ - 2 ;NEW COMMAND LINE
- NEW_TXT EQU NEW_CMD + 1 ;WHERE TEXT STARTS
- ASC_SEC DB 'SS' ;SECONDS IN ASCII
- DELIM DB ' ' ;NORMAL SPACE
- DB 64 DUP (?) ;REST OF COMMAND LINE
- LINE DB CR,LF,'Batch '
- TIME DB '00:00:00 '
- DATE DB '00-JAN-00 '
- LEN EQU $ - LINE
- LINEBUF DB 64 DUP (0)
- MONTH DB 'JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC'
- LOGF DB '\BATCH.LOG',0 ;PROCESS LOG FILE
- LOGCHAN DW ?
- BYTES DW ?
- ;
- EVEN
- DB 32 DUP ('STACK ')
- STK_TOP LABEL WORD
- ;
- INIT: MOV AX,CS
- MOV WORD PTR [BP_1],AX ;FOR 'LOAD AND EXECUTE'
- MOV WORD PTR [BP_2],AX
- MOV WORD PTR [BP_3],AX
- CALL SET_TIM ;SET PRIVATE TIME
- ;
- ; Check for graphics board
- ;
- PUSH DS ;SAVE DATA SEG
- XOR AX,AX ;ZERO IT
- MOV DS,AX
- MOV AL,BYTE PTR DS:[EQUIP] ;GET EQUIPMENT FLAG
- POP DS ;RESTORE DATA SEGMENT
- AND AL,00110000B ;MASK TRASH
- MOV WORD PTR [SEGMNT],BWSEG ;ASSUME SEGMENT FOR B/W
- CMP AL,00110000B ;IS IT BLACK AND WHITE?
- JZ SEG_OK ;YES
- MOV WORD PTR [SEGMNT],COSEG ;MUST BE COLOR
- ;
- SEG_OK: CALL PARSE ;PARSE COMMAND LINE
- JC FINIS ;BAD COMMAND LINE
- CALL GET_FLAG ;SET UP CRITICAL PROCESS FLAG
- CALL SET_INT ;SET UP INTERRUPTS
- CALL SET_TIM ;SET TIME AGAIN
- CALL KEEP3K
- KEEP: MOV AX,3100H ;KEEP PROCESS FUNCTION
- INT MS_DOS
- HLT ;IN CASE SOMETHING'S BUSTED
-
- FINIS: MOV AX,4C00H ;TERMINATE PROCESS
- INT MS_DOS
- MAIN ENDP
- ;
- CLK_INT PROC FAR
- ASSUME CS:PSEG,SS:PSEG,DS:PSEG,ES:NOTHING
- PUSH AX ;SAVE
- PUSH DS ;AND DS
- PUSH CS ;COPY CODE SEGMENT
- POP DS ;INTO DATA SEG
- ;
- ; We get interupted 18.2 times per second.
- ; Routine below produces 1 second 'Ticks' by
- ; dividing by 18.2 (honest). Subtracts 10 from 182
- ; each interupt and adds the remainder to 182 for
- ; the next run through the loop. Result is an AVERAGE
- ; division by 18.2.
-
- CMP BYTE PTR [CNT],0FFH ;FLAG SHOWS THAT WE TIMED OUT
- JZ BYPASS ;ALREADY TIMED OUT
- SUB BYTE PTR [CNT],10 ;RUNNING COUNT
- JNC BYPASS ;NO CARRY YET
- ADD BYTE PTR [CNT],182 ;CUTE EH?
- ;
- ; Simple 24 hour clock counter follows.
- ;
- INC BYTE PTR [SEC] ;BUMP SECONDS COUNTER
- CMP BYTE PTR [SEC],60 ;ARE WE THERE YET?
- JNZ TIM_OK ;NOPE
- MOV BYTE PTR [SEC],0 ;YES, ZERO SECONDS AND ....
- INC BYTE PTR [MIN] ;BUMP MINUTES
- CMP BYTE PTR [MIN],60 ;ARE WE THERE YET?
- JNZ TIM_OK ;NOPE
- MOV BYTE PTR [MIN],0 ;YES, ZERO MINUTES AND.... ETC
- INC BYTE PTR [HRS]
- CMP BYTE PTR [HRS],24
- JNZ TIM_OK
- MOV BYTE PTR [HRS],0
- ;
- ; Check new time against saved time from command line.
- ;
- TIM_OK: MOV AL,BYTE PTR [HRS] ;GET HOURS
- CMP AL,BYTE PTR [SAV_HRS] ;SAME AS SAVED?
- JNZ BYPASS ;NO
- MOV AL,BYTE PTR [MIN] ;GET MINUTES
- CMP AL,BYTE PTR [SAV_MIN] ;SAME AS SAVED?
- JNZ BYPASS ;NO
- MOV AL,BYTE PTR [SEC] ;GET SECONDS
- CMP AL,BYTE PTR [SAV_SEC] ;SAME AS SAVED?
- JNZ BYPASS ;NO
- MOV BYTE PTR [CNT],0FFH ;SET FLAG (WE ARE TIMED OUT)
- BYPASS: POP DS ;OLD DATA SEG
- POP AX ;AND AX
- JMP DWORD PTR CS:[OLD_CLK] ;CHAIN TO NEXT (IF ANY)
- CLK_INT ENDP
- ;
- ; This is the second clock interrupt vector.
- ;
- CLX_INT PROC FAR
- CMP BYTE PTR CS:[HERE],0 ;SEE IF REENTRY IS OCCURING
- JNZ HOME ;YES, DON'T ALLOW REENTRY
- CMP BYTE PTR CS:[CNT],0FFH ;SEE IF WE TIMED OUT
- JNZ HOME ;NO, NOT YET
- ;
- ; Check to see if we interrupted something important.
- ;
- PUSH BX
- PUSH DS
- LDS BX,DWORD PTR CS:[CRT_FLG] ;GET CRITICAL FLAG
- CMP BYTE PTR DS:[BX],0
- POP DS
- POP BX
- JZ TIMOUT ;OK TO MAKE DOS CALLS
- ;
- DONE: MOV BYTE PTR CS:[HERE],0 ;RESTORE REENTRY FLAG
- HOME: JMP DWORD PTR CS:[OLD_CLX] ;CONTINUE
- ;
- ; Coast is clear, save stack and continue.
- ;
- TIMOUT: MOV BYTE PTR CS:[HERE],0FFH ;SET ENTRY FLAG
- PUSH AX ;SAVE USER'S
- PUSH DS ;AND DS
- PUSH CS ;COPY CODE SEGMENT
- POP DS ;INTO DATA SEG
- CLI
- MOV WORD PTR [SS_SAV],SS ;SAVE IT
- MOV WORD PTR [SP_SAV],SP ;SAVE STACK POINTER
- MOV AX,CS ;GET CODE SEG
- MOV SS,AX ;INTO STACK SEG
- MOV SP,OFFSET STK_TOP ;LOCAL STACK
- ;
- PUSH BX ;SAVE EVERYTHING IN LOCAL STACK
- PUSH CX
- PUSH DX
- PUSH DI
- PUSH SI
- PUSH BP
- PUSH ES
- MOV ES,AX ;CODE SEGMENT INTO EXTRA SEG
- ;
- ; Run the program
- ;
- CODE PROC NEAR
- CALL RES_INT ;RESTORE OLD INTERRUPT VECTORS
- STI ;OK TO INTERRUPT
- CALL RES_HRD ;RESET HARDWARE CONTROLLER
- CALL SAV_SCR ;SAVE THE USER'S SCREEN
- CALL TELL ;TELL USER WHAT WE'RE DOING
- CALL LOG ;LOG TO DISK
- CALL SAV_DIR ;SAVE CURRENT DIRECTORY
- CALL SAV_DTA ;SAVE USERS DATA AREA
- CALL SET_DTA ;SET UP LOCAL DATA AREA
- CALL GET_MEM ;GET MORE MEMORY (dummy)
- JC NOFREE ;NOTHING AVAILABLE
- MOV ES,AX ;NEW SEGMENT ADDRESS OF AVAILABLE MEM
- NOFREE: CALL KEEP3K ;RESTORE TO POOL
- CALL RUN_PG ;LOAD/EXECUTE COMMAND.COM
- CALL RES_DTA ;RESTORE USERS DATA TRANSFER AREA
- CALL RES_DIR ;RESTORE CURRENT DIRECTORY
- CALL RES_SCR ;RESTORE USER'S SCREEN
- CALL KEEP0K ;GIVE UP ALL MEMORY
- CODE ENDP
- ;
- ; Return to user program.
- ;
- POP ES ;RESTORE USER'S REGISTERS
- POP BP ;SAVED IN LOCAL STACK
- POP SI
- POP DI
- POP DX
- POP CX
- POP BX
- ;
- CLI
- MOV SS,WORD PTR [SS_SAV] ;GET SAVED STACK SEG
- MOV SP,WORD PTR [SP_SAV] ;GET OLD STACK POINTER
- POP DS ;RESTORE REGISTERS FROM USER'S STACK
- POP AX
- STI ;ALLOW INTERRUPTS
- JMP DONE ;CONTINUE
- CLX_INT ENDP
- ;
- GET_MEM PROC NEAR
- MOV BX,40000 ;ASK FOR EVERYTHING IN THE COMPUTER
- MOV AH,4AH
- INT MS_DOS
- RET
- GET_MEM ENDP
- ;
- SET_TIM PROC NEAR
- MOV AH,2CH ;SET PRIVATE TIME
- INT MS_DOS
- MOV BYTE PTR [HRS],CH ;SAVE TIME IN PRIVATE CLOCK
- MOV BYTE PTR [MIN],CL
- MOV BYTE PTR [SEC],DH
- RET
- SET_TIM ENDP
- ;
- SET_INT PROC NEAR
- CLI
- CLD ;FOREWARD
- PUSH DS ;SAVE SEGMENT
- XOR AX,AX ;GET OLD INTERRUPT VECTOR
- MOV DS,AX ;FIRST SEGMENT IN MEMORY
- MOV SI,(CLK * 4) ;INTERRUPT ADDRESS
- LODSW ;GET OFFSET
- MOV WORD PTR CS:[IP_CLK],AX ;SAVE IN OUR CODE SEGMENT DS IS BUSY
- LODSW ;GET SEGMENT
- MOV WORD PTR CS:[CS_CLK],AX ;SAVE THAT TOO
- ;
- MOV SI,(CLX * 4) ;INTERRUPT ADDRESS
- LODSW ;GET OFFSET
- MOV WORD PTR CS:[IP_CLX],AX ;SAVE IN OUR CODE SEGMENT DS IS BUSY
- LODSW ;GET SEGMENT
- MOV WORD PTR CS:[CS_CLX],AX ;SAVE THAT TOO
- POP DS ;RESTORE OUR DATA SEG
- ;
- PUSH ES ;SAVE SEGMENT
- XOR AX,AX ;ZERO
- MOV ES,AX ;ZERO THE SEGMENT
- MOV DI,(CLK * 4) ;GET INTERRUPT ADDRESS
- MOV AX,OFFSET CLK_INT ;GET PROGRAM COUNTER
- STOSW ;PATCH
- MOV AX,CS ;GET CODE SEGMENT
- STOSW
- ;
- MOV DI,(CLX * 4) ;GET INTERRUPT ADDRESS
- MOV AX,OFFSET CLX_INT ;GET PROGRAM COUNTER
- STOSW ;PATCH
- MOV AX,CS ;GET CODE SEGMENT
- STOSW
- POP ES
- STI
- RET
- SET_INT ENDP
- ;
- ; Restore old clock vector(s).
- ;
- RES_INT PROC NEAR
- CLD ;FOREWARD
- CLI ;NO INTERRUPTS
- PUSH ES ;SAVE SEGMENT
- XOR AX,AX ;ZERO
- MOV ES,AX ;ZERO THE SEGMENT
- MOV DI,(CLK * 4) ;GET INTERRUPT ADDRESS
- MOV AX,WORD PTR [IP_CLK] ;GET PROGRAM COUNTER
- STOSW ;PATCH
- MOV AX,WORD PTR [CS_CLK] ;GET CODE SEGMENT
- STOSW
- ;
- MOV DI,(CLX * 4) ;GET INTERRUPT ADDRESS
- MOV AX,WORD PTR [IP_CLX] ;GET PROGRAM COUNTER
- STOSW ;PATCH
- MOV AX,WORD PTR [CS_CLX] ;GET CODE SEGMENT
- STOSW
- ;
- POP ES ;RESTORE SEGMENT
- STI ;ALLOW INTERRUPTS
- RET
- RES_INT ENDP
- ;
- GET_FLAG PROC NEAR ;GET CRITICAL DOS FLAG
- PUSH ES ;WILL RETURN IN ES SO SAVE
- MOV AH,34H ;FUNCTION
- INT MS_DOS ;DO IT
- MOV WORD PTR [DOS_FLG],BX ;SAVE IP
- MOV WORD PTR DOS_FLG[2],ES ;SAVE CS
- POP ES ;RESTORE EXTRA
- RET
- GET_FLAG ENDP
- ;
- PARSE PROC NEAR
- MOV SI,CMD_BUF ;POINT TO THE STRING
- LODSB ;GET BYTE FROM BUFFER
- OR AL,AL
- JZ BAD ;NOTHING TYPED
- CBW
- MOV CX,AX ;USE AS COUNT
- CALL CASE ;FORCE TO UPPER CASE
- MOV DI,SI ;COPY FOR COMPARE
- MOV AL,' ' ;LOOK FOR A SPACE
- REPZ SCASB ;GET BY SPACES
- JCXZ BAD ;NO SPACE
- MOV AL,':' ;DELIMITER _AFTER_ CHARACTER
- CALL GET_CHR ;GET CHARS, CONV TO BINARY
- JC BAD ;NO GOOD
- CMP AL,MAX_HRS ;WITHIN RANGE?
- JG BAD ;NOPE
- MOV BYTE PTR [SAV_HRS],AL ;SAVE GOOD BINARY
- MOV AL,':' ;NEXT DELIMITER
- CALL GET_CHR ;GET CHARACTER(S)
- JC BAD ;BAD CHARACTER(S)
- CMP AL,MAX_MIN ;WITHIN RANGE?
- JG BAD ;NOPE
- MOV BYTE PTR [SAV_MIN],AL ;SAVE GOOD BINARY
- MOV AL,' ' ;LOOK FOR SPACE
- CALL GET_CHR ;GET LAST CHARACTER(S)
- JC BAD ;IS GOOD
- CMP AL,MAX_SEC ;WITHIN RANGE?
- JG BAD ;NO
- MOV BYTE PTR [SAV_SEC],AL ;SAVE GOOD BINARY
- JMP SHORT CHKRES ;NOW, CHECK RESULTS
- ;
- BAD: MOV DX,OFFSET PRP4 ;POINT TO USAGE
- CALL PROMPT ;PRINT TO SCREEN
- STC ;SHOW ERROR
- RET
- ;
- CHKRES: CALL CHK_TIM ;SEE IF WE ENTERED TIME PROPERLY
- JNC TIMCHK ;IT WAS OK
- MOV DX,OFFSET PRP5 ;POINT TO 'IMPROPER TIME'
- CALL PROMPT ;PRINT
- STC ;SHOW ERROR
- RET
- ;
- TIMCHK: PUSH SI ;CHECK RESULTS
- MOV SI,OFFSET SAV_HRS ;WHERE BINARY IS
- MOV DI,OFFSET HH ;WHERE TO PUT ASCII
- CALL ASCIIM ;DO IT
- MOV SI,OFFSET SAV_MIN ;WHERE BINARY IS
- MOV DI,OFFSET MM ;WHERE TO PUT ASCII
- CALL ASCIIM ;DO IT
- MOV SI,OFFSET SAV_SEC ;WHERE BINARY IS
- MOV DI,OFFSET SX ;WHERE TO PUT ASCII
- CALL ASCIIM ;DO IT
- ;
- MOV DX,OFFSET PRP0 ;POINT TO 'PROCESS'
- CALL PROMPT ;PRINT TO SCREEN
- ;
- MOV DI,CMD_BUF ;POINT TO COMMAND LINE
- MOV AL,CL ;BYTE COUNT REMAINING
- ADD AL,3 ;BYTES FOR ' \C '
- STOSB
- PUSH CX ;SAVE PRESENT COUNT
- MOV CX,4 ;BYTES TO MOVE (TO WHERE TIME WAS)
- MOV SI,OFFSET INFORM ;STRING TO MOVE
- REP MOVSB ;MOVE INTO BUFFER
- POP CX ;RESTORE COUNT
- SUB CX,2 ;NO LEADING SPACE OR CARRIAGE RETURN
- POP SI ;GET SAVED STRING POINTER
- INC SI ;GET BY SPACE
- JCXZ ABRT ;NOTHING TO LOAD
- DISPL: LODSB ;GET BYTE
- STOSB ;SAVE IN START OF BUFFER
- CALL PCHR ;OUTPUT TO SCREEN
- LOOP DISPL ;UNTIL DONE
- MOV AL,CR ;BUFFER TERMINATION
- STOSB
- ;
- MOV DX,OFFSET PRP1 ;POINT TO 'IF NOT CORRECT..'
- CALL PROMPT ;PRINT TO SCREEN
- ;
- MOV CX,1000H ;TIMER
- WAIT0: MOV AH,06H ;DIRECT CONSOLE INPUT
- MOV DL,0FFH ;WE WANT A CHARACTER
- INT MS_DOS ;FROM DOS
- TEST AL,AL ;ANY CHARACTER?
- JNZ ABRT ;YES, ABORT
- TEST CL,CL ;NOPE, LOOK FOR CX = XX00
- JNZ NO_DIS ;DON'T DISPLAY
- MOV AL,CH ;GET HIGH BYTE
- TEST AL,11111000B ;WITHIN RANGE YET?
- JNZ NO_DIS ;NOPE, DON'T DISPLAY
- AND AL,00000111B ;YES, MASK HIGH BITS
- ADD AL,'0' ;CONVERT TO ASCII
- CALL PCHR ;PRINT TO SCREEN
- MOV AL,' ' ;GET A SPACE
- CALL PCHR ;PRINT IT TOO
- NO_DIS: LOOP WAIT0
- ;
- MOV DX,OFFSET PRP3 ;POINT TO 'LOADED'
- CALL PROMPT ;PRINT TO SCREEN
- XOR AX,AX ;NO CARRY
- RET
- ;
- ABRT: MOV DX,OFFSET PRP2 ;POINT TO 'ABORTED'
- CALL PROMPT ;PRINT TO SCREEN
- STC
- RET
- PARSE ENDP
- ;
- CHK_TIM PROC NEAR
- MOV AL,BYTE PTR [SAV_HRS] ;GET COMMAND INPUT HOURS
- CMP AL,BYTE PTR [HRS] ;GET PRESENT HOURS
- JZ CHKMIN ;HOURS ARE THE SAME
- JMP SHORT TIMBAD ;CARRY WILL SHOW ERROR
- CHKMIN: MOV AL,BYTE PTR [SAV_MIN] ;GET COMMAND INPUT MINUTES
- CMP AL,BYTE PTR [MIN] ;GET PRESENT MINUTES
- JZ CHKSEC ;IF THE SAME
- JMP SHORT TIMBAD ;CARRY SET IF BAD
- CHKSEC: MOV AL,BYTE PTR [SAV_SEC] ;GET COMMAND INPUT SECONDS
- CMP AL,BYTE PTR [SEC] ;GET PRESENT SECONDS
- TIMBAD: RET
- CHK_TIM ENDP
- ;
- PCHR PROC NEAR ;PRINT CHARACTER IN AL, USES AX,DX
- MOV DL,AL ;INTO DL
- MOV AH,2 ;CONTROL BYTE
- INT MS_DOS ;TO DOS
- RET
- PCHR ENDP
- ;
- TELL PROC NEAR
- MOV DX,OFFSET BEEP ;PRINT A BEEP
- PROMPT PROC NEAR ;PRINT STRING ADDRESSED BY DX
- MOV AH,9 ;FUNCTION
- INT MS_DOS ;SYSTEM
- RET
- PROMPT ENDP
- TELL ENDP
- ;
- GET_CHR PROC NEAR ;GET CHARACTER [DI] POINTER
- PUSH CX ;SAVE FOR NOW
- REPNZ SCASB ;GET BY DELIMITER
- POP BX ;SAVED AS FIRST COUNT (CX)
- JCXZ BADENTRY ;WERE NO DEMITERS
- SUB BX,CX ;BX= BYTES FROM SPACE TO ':'
- CMP BX,2 ;WAS IT TWO BYTES?
- PUSHF ;SAVE ANSWER TO THAT QUESTION
- DEC DI ;BACK TO 'FOUND' CHARACTER
- MOV SI,DI ;INTO SOURCE INDEX
- SUB SI,BX ;BACK UP TO FIRST BYTE
- LODSB ;GET BYTE
- SUB AL,'0' ;ASCII BIAS
- POPF ;ARE WE THROUGH?
- JNZ ALLDUN
- MOV BL,10 ;MULTIPLIER
- MUL BL ;TIMES TEN
- MOV AH,AL ;SAVE FOR NOW
- LODSB ;GET NEXT BYTE IN STRING
- SUB AL,'0' ;ASCII BIAS
- ADD AL,AH ;ADD TOGETHER
- ALLDUN: MOV DI,SI ;NEXT ADDRESS FOR COMPARE
- INC DI
- INC DI ;GET PAST THE COLON
- OR AL,AL ;CLEAR CARRY
- RET ;AL= BINARY FROM STRING
- BADENTRY:
- STC ;SHOW BAD
- RET
- GET_CHR ENDP
- ;
- CASE PROC NEAR
- PUSH SI ;SAVE INDEX
- PUSH CX ;AND COUNT
- MOV DI,SI ;DEST SAME AS SOURCE
- CASE0: LODSB ;GET BYTE
- CMP AL,'z' ;CHECK UPPER LIMIT
- JG NO_CVT ;NOT A LOWER CASE LETTER
- CMP AL,'a' ;CHECK LOWER LIMIT
- JL NO_CVT ;NOT A LOWER CASE LETTER
- AND AL,95 ;MASK LOWER CASE BITS
- NO_CVT: STOSB ;SAVE IN STRING
- LOOP CASE0
- POP CX ;RESTORE COUNT
- POP SI ;AND INDEX
- RET
- CASE ENDP
- ;
- RUN_PG PROC NEAR ;LOAD AND EXECUTE PROGRAM
- MOV WORD PTR [SSP_SAV],SP ;SAVE STACK POINTER
- MOV AX,4B00H ;RUN PROGRAM EXE CALL
- MOV BX,OFFSET BLOCK ;POINT TO PARAMETER BLOCK
- MOV DX,OFFSET COMMAND ;POINT TO FILENAME
- INT MS_DOS ;DO IT
- MOV AX,CS ;GET GODE SEGMENT
- MOV DS,AX ;SEGMENT FIXUPS
- MOV ES,AX
- MOV SS,AX ;FIX UP STACK SEGMENT
- MOV SP,WORD PTR [SSP_SAV] ;RESTORE LOCAL STACK
- RET
- RUN_PG ENDP
- ;
- KEEP3K PROC NEAR
- MOV BX,OFFSET TOP ;PARAGRAPHS TO KEEP
- MOV CL,4 ;BITS TO SHIFT
- SHR BX,CL
- INC BX ;ROUND UP
- JMP SHORT FRE_MEM ;IMPLIED RETURN
- KEEP3K ENDP
- ;
- KEEP0K PROC NEAR
- XOR BX,BX ;NO PARAGRAPHS
- FRE_MEM PROC NEAR ;FREE UP MEMORY (PARAS IN BX)
- MOV AH,4AH ;FUNCTION
- PUSH ES ;SAVE, GET'S DESTROYED
- INT MS_DOS ;DO IT
- POP ES ;RESTORE EXTRA
- RET
- FRE_MEM ENDP
- KEEP0K ENDP ;FALL THROUGH
- ;
- SAV_SCR PROC NEAR ;SAVE ALL SCREEN PAGES BY BRUTE FORCE!
- CALL GET_CUR ;SAVE CURSOR POSITION
- CALL CREATE ;CREATE A SCREEN DATA FILE
- CALL WRITE ;WRITE SCREEN DATA TO FILE
- PUSHF ;SAVE POSSIBLE ERROR ON THE WRITE
- CALL CLOSE ;CLOSE THE FILE
- CALL CLR_SCR ;CLEAR THE SCREEN
- POPF ;GET ERROR CODE FROM WRITE
- JZ SAV_OK ;WAS ENOUGH SPACE
- MOV DX,OFFSET ERRW ;POINT TO ERROR MESSAGE
- CALL PROMPT ;PRINT TO SCREEN
- SAV_OK: RET ;THAT'LL DO IT
- SAV_SCR ENDP
- ;
- GET_CUR PROC NEAR ;GET CURSOR POSITION
- MOV AH,15 ;GET CURRENT STATE
- INT VID_ROM
- XOR BL,BL ;PAGE RETURNS IN BH
- MOV BYTE PTR [CUR_PGE],BH ;SAVE CURRENT PAGE
- MOV AH,3 ;FUNCTION
- INT VID_ROM ;DO IT
- MOV WORD PTR [CUR_SAV],DX ;SAVE CURSOR POSITION
- MOV WORD PTR [CUR_TYP],CX ;SAVE CURSOR TYPE
- RET
- GET_CUR ENDP
- ;
- RES_SCR PROC NEAR ;RESTORE SCREEN
- CALL SET_CUR ;RESTORE OLD CURSOR POSITION
- CALL OPEN ;OPEN THE SCREEN DATA FILE
- CALL READ ;READ INTO SCREEN MEMORY
- CALL CLOSE ;CLOSE THE FILE
- CALL DELETE ;AND BLOW IT AWAY
- RET
- RES_SCR ENDP
- ;
- SET_CUR PROC NEAR ;SET CURSOR TO SAVED POSITION
- MOV AL,BYTE PTR [CUR_PGE] ;GET 'OLD' CURRENT PAGE
- MOV AH,5 ;SELECT PAGE FUNCTION
- INT VID_ROM ;DO IT
- MOV AH,2 ;FUNCTION
- MOV BH,BYTE PTR [CUR_PGE] ;PAGE
- MOV DX,WORD PTR [CUR_SAV] ;GET OLD POSITION
- INT VID_ROM ;DO IT
- MOV AH,1 ;SET CURSOR TYPE
- MOV CX,WORD PTR [CUR_TYP] ;GET CURSOR TYPE
- INT VID_ROM
- RET
- SET_CUR ENDP
- ;
- CLR_SCR PROC NEAR ;CLEAR THE SCREEN
- MOV AX,0600H ;FUNCTION
- XOR CX,CX ;TOP LEFT HAND CORNER
- MOV DX,244FH ;BOTTOM RIGHT
- MOV BH,7 ;NORMAL ATTRIBUTE
- INT VID_ROM ;DO IT
- XOR DX,DX ;TOP LEFT CORNER
- MOV AH,2 ;SET CURSOR FUNCTION
- MOV BH,0 ;PAGE ZERO
- INT VID_ROM ;SET THE CURSOR
- MOV AH,1 ;SET CURSOR TYPE
- MOV CX,0608H ;START LINE 6, END LINE
- INT VID_ROM
- RET
- CLR_SCR ENDP
- ;
- SAV_DTA PROC NEAR ;SAVE USERS DTA
- PUSH ES ;SAVE, SEGMENT IN RETURN
- MOV AH,2FH ;GET PRESENT DTA
- INT MS_DOS ;CALL DOS
- MOV WORD PTR [DTA_SEG],ES ;SAVE PRESENT DTA SEGMENT
- MOV WORD PTR [DTA_OFF],BX ;SAVE PRESENT DTA OFFSET
- POP ES ;RESTORE SEGMENT
- RET
- SAV_DTA ENDP
- ;
- SET_DTA PROC NEAR ;SET NEW DTA TO 'DEFAULT'
- MOV AH,1AH ;FUNCTION
- MOV DX,CMD_BUF ;DS:DX = 80H
- INT MS_DOS ;DO IT
- RET
- SET_DTA ENDP
- ;
- RES_DTA PROC NEAR ;RESTORE USER'S DTA
- MOV AH,1AH ;FUNCTION
- MOV DX,WORD PTR [DTA_OFF] ;GET OLD OFFSET
- PUSH DS ;SAVE PRESENT DATA SEG
- MOV DS,WORD PTR [DTA_SEG] ;NEW (OLD USER'S) DATA SEG
- INT MS_DOS ;RESET TO OLD
- POP DS ;RESTORE DATA SEG
- RET
- RES_DTA ENDP
- ;
- RES_HRD PROC NEAR ;RESET HARDWARE CONTROLLER
- MOV CX,5 ;FIVE POSSIBLE INTERRUPTS
- MOV AL,20H ;NON-SPECIFIC END OF INTERRUPT
- HRD: OUT INT_BASE,AL
- LOOP HRD
- RET
- RES_HRD ENDP
- ;
- SAV_DIR PROC NEAR
- MOV AH,19H ;CURRENT DISK FUNCTION
- INT MS_DOS
- MOV BYTE PTR [DISK],AL ;SAVE
- ;
- MOV AH,47H ;GET DIRECTORY FUNCTION
- MOV SI,OFFSET DIRECT
- MOV DL,0 ;CURRENT DISK
- INT MS_DOS
- RET
- SAV_DIR ENDP
- ;
- RES_DIR PROC NEAR
- MOV AH,0EH ;SELECT DISK FUNCTION
- MOV DL,BYTE PTR [DISK] ;GET SAVED DRIVE
- INT MS_DOS ;DO IT
- MOV AH,3BH ;CHANGE DIRECTORY FUNCTION
- MOV DX,OFFSET DIRZ
- INT MS_DOS
- RET
- RES_DIR ENDP
- ;
- ;
- ; The following routines are used to save the screen data on a disk.
- ;
- COPY PROC NEAR ;COPY FILE NAME, DOS KILLS IT!!!
- MOV SI,OFFSET FILE1 ;COPY FROM HERE
- MOV DI,OFFSET FILE2 ;PUT IT THERE
- MOV CX,FILEN ;BYTES TO COPY
- REP MOVSB ;DO IT
- RET
- COPY ENDP
- ;
- CREATE PROC NEAR
- CALL COPY
- MOV AH,3CH ;MS DOS FUNCTION
- MOV DX,OFFSET FILE2 ;POINTER TO FILE NAME
- XOR CX,CX ;NORMAL ATTRIBUTES
- INT MS_DOS ;DO IT
- MOV WORD PTR [HANDLE],AX ;SAVE HANDLE
- RET
- CREATE ENDP
- ;
- OPEN PROC NEAR
- CALL COPY ;GET NEW COPY OF FILE NAME
- MOV AX,3D00H ;OPEN FUNCTION FOR READING
- MOV DX,OFFSET FILE2 ;POINT TO FILE NAME
- INT MS_DOS
- MOV WORD PTR [HANDLE],AX ;SAVE ACCESS WORD
- RET
- OPEN ENDP
- ;
- WRITE PROC NEAR
- MOV AH,40H ;WRITE TO FILE FUNCTION
- MOV BX,WORD PTR [HANDLE] ;GET OPEN FILE HANDLE
- MOV CX,K16 ;16 K TO WRITE
- PUSH DS ;SAVE DATA SEG
- MOV DS,WORD PTR [SEGMNT] ;GET SCREEN SEGMENT
- XOR DX,DX ;START AT THE BOTTOM
- INT MS_DOS ;WRITE IT
- POP DS ;RESTORE SEGMENT
- CMP AX,K16 ;DID WE GET IT ALL?
- RET
- WRITE ENDP
- ;
- READ PROC NEAR
- MOV AH,3FH ;READ FILE FUNCTION
- MOV BX,WORD PTR [HANDLE] ;FILE ACCESS WORD
- MOV CX,K16 ;16 K TO READ INTO SCREEN
- PUSH DS ;SAVE DATA SEGMENT
- MOV DS,WORD PTR [SEGMNT] ;GET SCREEN SEGMENT
- XOR DX,DX ;START AT THE BOTTOM
- INT MS_DOS ;READ INTO SCREEN MEMORY
- POP DS ;RESTORE
- RET
- READ ENDP
- ;
- CLOSE PROC NEAR ;CLOSE THE SCREEN DATA FILE
- MOV AH,3EH ;FUNCTION
- MOV BX,WORD PTR [HANDLE] ;FILE ACCESS WORD
- INT MS_DOS ;DO IT
- RET
- CLOSE ENDP
- ;
- DELETE PROC NEAR ;DELETE SCREEN DATA FILE
- CALL COPY ;GET FRESH COPY OF FILE NAME
- MOV AH,41H ;DELETE FUNCTION
- MOV DX,OFFSET FILE2 ;POINT TO FILE NAME
- INT MS_DOS ;BLOW IT AWAY
- RET
- DELETE ENDP
- ;
- ; The following routines log the operation to disk
- ;
- LOG PROC NEAR
- CALL OPEN_LOG
- CALL FIND_END
- CALL GET_TIME
- CALL GET_DATE
- CALL GET_PROC
- CALL WRITE_LOG
- CALL CLOSE_LOG
- RET
- LOG ENDP
- ;
- GET_TIME PROC NEAR
- MOV AH,2CH ;GET TIME FUNCTION
- INT MS_DOS
- MOV DI,OFFSET TIME
- MOV AL,CH ;HOURS TO AL
- CALL ASCII ;CONV TO ASCII
- INC DI ;GET BY ':'
- MOV AL,CL ;MINUTES TO AL
- CALL ASCII ;CONV TO ASCII
- INC DI ;GET BY ':'
- MOV AL,DH ;SECS TO AL
- CALL ASCII ;CONVERT TO ASCII
- RET
- GET_TIME ENDP
- ;
- GET_DATE PROC NEAR
- MOV AH,2AH
- INT MS_DOS
- PUSH CX ;SAVE YEAR
- MOV AL,DL ;GET DAY
- MOV DI,OFFSET DATE
- CALL ASCII
-
- MOV DI,OFFSET DATE[3]
- MOV AL,DH ;GET MONTHS
- DEC AL ;JAN IS NOW ZERO OFFSET
- CBW ;A WORD
- MOV CL,3 ;MULTIPLIER (THREE CHRS PER MONTH)
- MUL CL ;CALC OFFSET
- MOV SI,OFFSET MONTH ;POINT TO TABLE
- ADD SI,AX ;NEW OFFSET
- MOV CX,3 ;CHRS TO MOVE
- REP MOVSB ;DO IT
- POP CX
- SUB CX,1900 ;NORMALIZE
- MOV AL,CL
- MOV DI,OFFSET DATE[7]
- CALL ASCII
- RET
- GET_DATE ENDP
- ;
- GET_PROC PROC NEAR
- MOV WORD PTR [BYTES],0 ;BYTE COUNT
- MOV SI,CMD_BUF ;POINT TO COMMAND LINE
- MOV DI,OFFSET LINEBUF ;WHERE TO PUT THE STRING
- LODSB ;GET CHARACTERS TYPED
- SUB AL,3 ;SUBTRACT FOR ' /C'
- CBW
- MOV CX,AX ;BYTE COUNT
- JCXZ GETOUT ;NOTHING TYPED
- ADD AX,LEN ;PLUS THE TIME/DATE STAMP
- MOV WORD PTR [BYTES],AX ;SAVE FOR FILE WRITE
- ADD SI,3 ;GET BY THE ' /C'
- REP MOVSB ;MOVE THE STRING
- GETOUT: RET
- GET_PROC ENDP
- ;
- OPEN_LOG PROC NEAR
- MOV DX,OFFSET LOGF ;POINT TO LOG FILE NAME
- MOV AX,3D02H ;OPEN FOR R/W
- XOR CX,CX ;NORMAL FILE
- INT MS_DOS
- JNC OPNGD ;GOOD OPEN
- MOV AX,3C00H ;CREATE THE FILE, NONE EXISTS
- MOV DX,OFFSET LOGF ;POINT TO FILE NAME
- XOR CX,CX ;NORMAL FILE
- INT MS_DOS
- OPNGD: MOV WORD PTR [LOGCHAN],AX ;SAVE CHANNEL ACCESS WORD
- RET
- OPEN_LOG ENDP
- ;
- FIND_END PROC NEAR
- MOV AX,4202H ;MOVE TO END PLUS OFFSET
- XOR CX,CX
- MOV DX,CX ;NO OFFSET
- MOV BX,WORD PTR [LOGCHAN] ;GET HANDLE
- INT MS_DOS ;DO IT
- RET
- FIND_END ENDP
- ;
- WRITE_LOG PROC NEAR
- MOV AX,4000H ;WRITE TO FILE
- MOV DX,OFFSET LINE ;POINT TO THE STRING TO BE WRITTEN
- MOV BX,WORD PTR [LOGCHAN] ;HANDLE
- MOV CX,WORD PTR [BYTES] ;NOW MUCH TO WRITE
- JCXZ NOWRT
- INT MS_DOS
- NOWRT: RET
- WRITE_LOG ENDP
- ;
- CLOSE_LOG PROC NEAR
- MOV AX,3E00H ;CLOSE FILE
- MOV BX,WORD PTR [LOGCHAN] ;FILE ACCESS WORD
- INT MS_DOS
- RET
- CLOSE_LOG ENDP
- ;
- ASCIIM PROC NEAR ;BINARY(M) TO ASCII
- LODSB
- ASCII PROC NEAR ;CONV BINARY IN AL TO ASCII [DI]
- MOV AH,'0'-1 ;ASCII BIAS
- SUBT: INC AH ;TENS COUNTER
- SUB AL,10 ;SUBTRACT TENS
- JNC SUBT ;CONTINUE
- ADD AL,(10 + '0') ;ONE TOO MANY ADD BACK PLUS ASCII BIAS
- XCHG AH,AL ;SWAP FOR STRING STORE
- STOSW ;DO IT
- RET
- ASCII ENDP
- ASCIIM ENDP
- ;
- TOP EQU $
- IF1
- %OUT -------
- ENDIF
- PSEG ENDS
- END MAIN